#pragma once

#include "Common/Singleton.h"
#include "Server/WorkerThread.h"
#include "TcpServerWrapper.h"
#include "LogicWorker.h"
#include "DBCache/DBWorker.h"
#include "Cfg.h"

#define THREAD_COUNT	3
enum {
	Thread_Logic = 0x01,
	Thread_DB = 0x02,
	Thread_Http = 0x03,
};

using namespace Network;

class DBConnectionMgr;

extern const char * s_HelpInfo;
extern UInt8 SERVER_TYPE;
extern UInt32 SERVER_ID;
extern std::string SERVER_NAME;
extern DBConnectionMgr * gDataDBConnectionMgr;
extern DBConnectionMgr * gPlatDBConnectionMgr;
extern DBConnectionMgr * gObjectDBConnectionMgr;

class HttpService;
class RoomManager;
class GameReportManager;
class Server
	: public Singleton<Server>
{
protected:
	Server();
	virtual ~Server();
	friend class Singleton<Server>;

public:
	bool init();
	void run();
	void shutdown();
	void unInit();
	void setAlive(bool = true);
	bool getAlive() const;
	bool parseCommandInfo(Int32, char **);
	std::string& getWorkDirectory();
	std::string  getFilePath(const std::string&);

public:
	inline Network::TcpServerWrapper * getTcpService() { return _tcpService; }
	inline LogicWorker& getLogicWorker()
	{
		return (dynamic_cast<WorkerThread<LogicWorker>*>(_logicWorker))->Worker();
	}
	inline DBWorker& getDBWorker()
	{
		return (dynamic_cast<WorkerThread<DBWorker>*>(_dbWorker))->Worker();
	}

	RoomManager * getRoomManager()	{ return _roomManager; }
	ServerClientManager * getServerClientManager()	{ return _serverClientManager; }
	GameReportManager * getGameReportManager() { return _greportManager; }
	HttpService * getHttpSerrvice() { return _httpService; }

protected:
	std::string			_workerDirectory;
	std::string			_serverName;
	BaseThread *		_logicWorker;
	BaseThread *		_dbWorker;
	TcpServerWrapper *	_tcpService;
	RoomManager *		_roomManager;
	ServerClientManager * _serverClientManager;
	GameReportManager * _greportManager;

protected:
	HttpService *		_httpService;
	wch::Thread	 *		_httpWorker;
};

#define SERVER()	 Server::Instance()
#define NETWORK()	 SERVER().getTcpService()
#define LOGIC()	     SERVER().getLogicWorker()
#define DB()	     SERVER().getDBWorker()
#define PM()		 LOGIC().getPlayerManager()
#define RM()		 SERVER().getRoomManager()
#define SCM()		 SERVER().getServerClientManager()
#define GRM()		 SERVER().getGameReportManager()
#define HTTP()		 SERVER().getHttpSerrvice()

#define CURRENT_THREAD_ID() WorkerThread<WorkerRunner<> >::LocalWorker().GetThreadID()